package cn.elane.elastic.global.model;

import cn.elane.elastic.global.util.StringUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @author Chenyu
 * @date 2019-10-30
 */
public class NameBeanUtil {

	private static final String OBJECT_PREFIX = "{";
	private static final String OBJECT_SUFFIX = "}";

	private static final String ARRAY_PREFIX = "[{";
	private static final String ARRAY_SUFFIX = "}]";

	/**
	 * 判断是否符合json对象格式.
	 *
	 * @param str p
	 * @return r
	 */
	public static Boolean ifObjectStr(String str) {
		if (str == null || str.trim().length() == 0) {
			return false;
		}
		str = str.trim();
		try {
			if (str.startsWith(OBJECT_PREFIX) && str.endsWith(OBJECT_SUFFIX)) {
				JSONObject jo = JSONObject.parseObject(str);
				return jo != null && !jo.isEmpty();
			}
			return false;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * 判断是否符合json对象数组格式.
	 *
	 * @param str p
	 * @return r
	 */
	public static Boolean ifArrayStr(String str) {
		if ((str == null || str.trim().length() == 0)) {
			return false;
		}
		str = str.trim();
		try {
			if (str.startsWith(ARRAY_PREFIX) && str.endsWith(ARRAY_SUFFIX)) {
				JSONArray ja = JSONArray.parseArray(str);
				return ja != null && !ja.isEmpty();
			} else {
				return false;
			}
		} catch (Exception e) {
			return false;
		}
	}

	/**
	 * 只处理[{...},{...},{...}]格式的数据.
	 *
	 * @param jsonStr [{...},{...},{...}]
	 * @return List<Bean>
	 */
	public static List<NameBean> init2List(String jsonStr) {
		List<NameBean> list;
		if (ifArrayStr(jsonStr)) {
			jsonStr = jsonStr.replaceAll("[\n\r]", "").replaceAll("[\t]", "    ");
			JSONArray obj = JSONArray.parseArray(jsonStr.trim());
			if (obj != null) {
				list = new ArrayList<>();
				for (Object o : obj) {
					list.add(new NameBean(o.toString()));
				}
				return list;
			} else {
				System.err.println("json格式不正确！");
				return null;
			}
		} else {
			System.err.println("json格式不正确！");
			return null;
		}
	}

	public static String toJson(List<NameBean> list) {
		if (list != null && !list.isEmpty()) {
			StringBuilder sb = new StringBuilder("[");
			for (NameBean obj : list) {
				sb.append(obj.toJson().replaceAll("[\n\r]", "\\\\n")).append(",");
			}
			if (sb.toString().endsWith(",")) {
				int len = sb.length();
				sb.delete(len - 1, len);
			}
			return sb.append("]").toString();
		} else {
			return "[]";
		}
	}

	public static String toJsonObj(List<Object> list) {
		if (list != null && !list.isEmpty()) {
			StringBuilder sb = new StringBuilder("[");
			for (Object obj : list) {
				if (obj instanceof NameBean) {
					sb.append(((NameBean) obj).toJson().replaceAll("[\n\r]", "\\\\n")).append(",");
				} else if (ifObjectStr(obj.toString())) {
//                    sb.append(obj.toString()).append(",");
					sb.append((new NameBean(obj.toString())).toJson().replaceAll("[\n\r]", "\\\\n")).append(",");
				} else {
					sb.append("\"").append(obj.toString().replaceAll("[\n\r]", "\\\\n")).append("\"").append(",");
				}
			}
			if (sb.toString().endsWith(",")) {
				int len = sb.length();
				sb.delete(len - 1, len);
			}
			return sb.append("]").toString();
		} else {
			return "[]";
		}
	}

	/**
	 * 指定单个name,返回一个list集合.<br>重复会被覆盖!
	 *
	 * @param list 集合
	 * @param name 单个name
	 * @return
	 */
	public static List<String> toList(List<NameBean> list, String name) {
		if (list != null && list.size() > 0) {
			List<String> rs = new ArrayList<>(list.size());
			for (NameBean l : list) {
				rs.add(l.str(name));
			}
			return rs;
		}
		return null;
	}

	/**
	 * 指定单个name,返回一个数组.<br>重复数据不会被覆盖!
	 *
	 * @param list 集合
	 * @param name 单个name
	 * @return
	 */
	public static String[] toArray(List<NameBean> list, String name) {
		if (list != null && list.size() > 0) {
			String[] rs = new String[list.size()];
			for (int i = 0; i < list.size(); i++) {
				rs[i] = (list.get(i).str(name));
			}
			return rs;
		}
		return null;
	}

	/**
	 * 将List转为Bean<br>
	 * <code>[
	 * {
	 * "label":"对象名称",
	 * "uuid":"name",
	 * "object":"object"
	 * },<br>
	 * {
	 * "label":"对象ID",
	 * "uuid":"uuid",
	 * "object":"object"
	 * }
	 * ]</code><br>
	 * 根据object转为:<br>
	 * <code>{
	 * "object":[
	 * {
	 * "label":"对象名称",
	 * "uuid":"name",
	 * "object":"object"
	 * },
	 * {
	 * "label":"对象ID",
	 * "uuid":"uuid",
	 * "object":"object"
	 * }
	 * ]
	 * }</code><br>
	 * 根据object,uuid转为:<br>
	 * <code>{
	 * "object":{<br>
	 * "name":{
	 * "label":"对象名称",
	 * "uuid":"name",
	 * "object":"object"
	 * },<br>
	 * "uuid":{
	 * "label":"对象ID",
	 * "uuid":"uuid",
	 * "object":"object"
	 * }<br>
	 * }
	 * }</code>
	 *
	 * @param list  待转list
	 * @param alias 一个alias代表一个层级
	 * @return Bean
	 */
	public static NameBean toBean(List<NameBean> list, String... alias) {
		if (list == null || list.size() == 0 || alias == null || alias.length == 0) {
			return null;
		}
		NameBean bean = new NameBean();
		StringBuilder keyStr = new StringBuilder();
		for (NameBean obj : list) {
			keyStr.delete(0, keyStr.length());
			for (String key : alias) {
				if (keyStr.length() > 0) {
					keyStr.append(".");
				}
				keyStr.append(obj.str(key));
			}
			bean.add(keyStr.toString(), obj);
		}
		return bean;
	}

	/**
	 * 将List&lt;Map&gt转为List&lt;NameBean&gt
	 *
	 * @param obj
	 * @return
	 */
	public static List<NameBean> mapList2NameBeanList(List<Map<String, Object>> obj) {
		if (obj == null) {
			return null;
		}
		if (obj.size() == 0) {
			return new ArrayList<>();
		}
		List<NameBean> list = new ArrayList<>(obj.size());
		for (Map<String, Object> o : obj) {
			list.add(new NameBean().init(o));
		}
		return list;
	}

	/**
	 * 根据上级值进行tree结构转换
	 *
	 * @param list 集合
	 * @param id   唯一键
	 * @param pId  上级唯一键
	 * @param keys 需要保留的键名列表
	 * @param pVal 上级值
	 * @return tree集合.子级key默认为children
	 */
	public static List<NameBean> toTreeList(List<NameBean> list, String id, String pId, Object pVal, String... keys) {
		if (list == null || list.size() == 0 || id == null || id.trim().length() == 0 || pId == null || pId.trim().length() == 0 || pVal == null) {
			return null;
		}
		return toTreeList(list, id, pId, pVal, (keys == null || keys.length == 0) ? null : Arrays.asList(keys));
	}

	/**
	 * 根据上级值进行tree结构转换
	 *
	 * @param list 集合
	 * @param id   唯一键
	 * @param pId  上级唯一键
	 * @param keys 需要保留的键名列表,null则保留所有.
	 * @param pVal 上级值
	 * @return tree集合.子级key默认为children
	 */
	public static List<NameBean> toTreeList(List<NameBean> list, String id, String pId, Object pVal, List<String> keys) {
		if (list == null || list.size() == 0 || id == null || id.trim().length() == 0 || pId == null || pId.trim().length() == 0 || pVal == null) {
			return null;
		}
		List<NameBean> child = new ArrayList<>();
		for (NameBean l : list) {
			if (pVal.equals(l.obj(pId))) {
				if (keys != null && keys.size() > 0) {
					child.add(l.cut(keys));
				} else {
					child.add(l.copy());
				}
			}
		}
		if (child.size() > 0) {
			List<NameBean> temp;
			for (NameBean c : child) {
				temp = toTreeList(list, id, pId, c.obj(id), keys);
				if (temp != null) {
					c.put("children", temp);
				}
			}
			return child;
		}
		return null;
	}

	/**
	 * 将list集合转为NameBean容器
	 *
	 * @param list 集合
	 * @param key  唯一键
	 * @return NameBean
	 */
	public static NameBean listToBean(List<NameBean> list, String key) {
		if (list == null || list.size() == 0 || key == null || key.trim().length() == 0) {
			return null;
		}
		NameBean rs = new NameBean();
		for (NameBean l : list) {
			rs.put(l.str(key), l);
		}
		return rs.size() > 0 ? rs : null;
	}

	/**
	 * 根据指定的别名列表进行裁剪
	 *
	 * @param list  待裁剪的集合
	 * @param alias 别名列表:key1,key2
	 * @return 裁剪后的NameBean集合
	 */
	public static List<NameBean> cut(List<NameBean> list, String[] alias) {
		if (list == null || list.size() == 0 || alias == null || alias.length == 0) {
			return null;
		}
		List<NameBean> rs = new ArrayList<>(list.size());
		for (NameBean l : list) {
			rs.add(l.cut(alias));
		}
		return rs;
	}

	/**
	 * 根据指定的别名列表进行裁剪
	 *
	 * @param list  待裁剪的集合
	 * @param alias 别名列表:key1
	 * @return 裁剪后的String集合
	 */
	public static List<String> cut(List<NameBean> list, String alias) {
		if (list == null || list.size() == 0 || alias == null || alias.trim().length() == 0) {
			return null;
		}
		List<String> rs = new ArrayList<>(list.size());
		for (NameBean l : list) {
			rs.add(l.str(alias));
		}
		return rs;
	}

	/**
	 * 将NameBean-->key:NameBean格式的,转为值(NameBean)集合
	 *
	 * @param param 参数
	 * @return NameBean集合
	 */
	public static List<NameBean> valueList(NameBean param) {
		if (param == null || param.isEmpty()) {
			return null;
		}
		List<NameBean> rs = new ArrayList<>(param.size());
		param.forEach((key, val) -> rs.add((NameBean) val));
		return rs;
	}
}
